﻿
using System;
using System.Text;

namespace RayDen.RayEngine.VertexFramework
{
    public class PathExpressionHelper
    {
        public static string GetVertexExpression(ref PathVertex v)
        {
            if (v.HitType == PathVertexType.Environment)
            {
                return "A";
            }

            if (v.HitType == PathVertexType.SpecularLightsource)
            {
                return "L";
            }
            if (v.HitType == PathVertexType.Geometry && v.Material != null)
            {
                if (v.Material.IsDiffuse())
                    return "D";
                if (v.Material.IsSpecular() || v.Material.IsRefractive())
                    return "S";
            }

            return " ";
        }


        public static string GetPathExpression(UInt64 PathExpressionData, int length)
        {
            var sb = new StringBuilder();

            var mask = 7u;
            for (int i = 0, offs = 0; i < length; i++, offs += 3)
            {
                var pt = (PathVertexType)((PathExpressionData >> offs) & mask);
                sb.Append(pt.ToPathString());
                if (pt == PathVertexType.Environment)
                    break;
            }
            return sb.ToString();
        }



        public static bool Contains( UInt64 PathExpressionData, int depth, PathVertexType tt )
        {
            const uint mask = 7u;
            for (int i = 0, offs = 0; i < depth; i++, offs += 3)
            {
                var pt = (PathVertexType)((PathExpressionData >> offs) & mask);
                if (pt == tt)
                    return true;
            }
            return false;
        }


        public static bool EndsWith( UInt64 PathExpressionData, int depth, params PathVertexType[] tt )
        {
            const uint mask = 7u;
            var offset = (depth - 1) * 3;
            var ptv = (PathVertexType)((PathExpressionData >> offset) & mask);
            for (var i = 0; i < tt.Length; i++)
            {
                if (tt[i] == ptv)
                    return true;
            }
            return false;
        }
    }
}
